#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef double db;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+ch-'0'; ch=getchar(); }
	return x*f;
}
const int MAXN=1010,INF=0x3f3f3f3f;
int a,b,n,v[MAXN][MAXN],_max[MAXN][MAXN],_min[MAXN][MAXN],l,r,ans,mx[MAXN],mn[MAXN];
struct node
{
	int num,i;
}q[MAXN];
int main()
{
	a=read();b=read();n=read();
	for(int i=1;i<=a;++i)
		for(int j=1;j<=b;++j)
			v[i][j]=read();
	for(int i=1;i<=a;++i)
	{
		l=1;r=0;
		for(int j=1;j<=b;++j)
		{
			while(r-l>=n||q[l].i<=j-n)++l;
			while(l<=r&&q[r].num<=v[i][j])--r;
			q[++r]=(node){v[i][j],j};
			if(j>=n)_max[i][j]=q[l].num;
		}
		l=1;r=0;
		for(int j=1;j<=b;++j)
		{
			while(r-l>=n||q[l].i<=j-n)++l;
			while(l<=r&&q[r].num>=v[i][j])--r;
			q[++r]=(node){v[i][j],j};
			if(j>=n)_min[i][j]=q[l].num;
		}
	}
	ans=INF;
	for(int i=n;i<=b;++i)
	{
		l=1;r=0;
		for(int j=1;j<=a;++j)
		{
			while(r-l>=n||q[l].i<=j-n)++l;
			while(l<=r&&q[r].num<=_max[j][i])--r;
			q[++r]=(node){_max[j][i],j};
			if(j>=n)mx[j]=q[l].num;
		}
		l=1;r=0;
		for(int j=1;j<=a;++j)
		{
			while(r-l>=n||q[l].i<=j-n)++l;
			while(l<=r&&q[r].num>=_min[j][i])--r;
			q[++r]=(node){_min[j][i],j};
			if(j>=n)mn[j]=q[l].num;
		}
		for(int j=n;j<=a;++j)ans=min(ans,mx[j]-mn[j]);
	}
	printf("%d\n",ans);
	return 0;
}
